// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network;

import java.util.Arrays;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.core.network.ByteBufferWriter;
import zombie.iso.IsoUtils;

public class MPStatisticClient {
    public static MPStatisticClient instance = new MPStatisticClient();
    private boolean needUpdate = true;
    private int zombiesLocalOwnership = 0;
    private float zombiesDesyncAVG = 0.0F;
    private float zombiesDesyncMax = 0.0F;
    private int zombiesTeleports = 0;
    private float remotePlayersDesyncAVG = 0.0F;
    private float remotePlayersDesyncMax = 0.0F;
    private int remotePlayersTeleports = 0;
    private float FPS = 0.0F;
    long lastRender = System.currentTimeMillis();
    short FPSAcc = 0;
    private float[] fpsArray = new float[1000];
    private short fpsArrayCount = 0;

    public static MPStatisticClient getInstance() {
        return instance;
    }

    public void incrementZombiesTeleports() {
        this.zombiesTeleports++;
    }

    public void incrementRemotePlayersTeleports() {
        this.remotePlayersTeleports++;
    }

    public float getFPS() {
        return this.FPS;
    }

    public void update() {
        if (this.needUpdate) {
            this.needUpdate = false;

            for (int _int = 0; _int < GameClient.IDToZombieMap.values().length; _int++) {
                IsoZombie isoZombie = (IsoZombie)GameClient.IDToZombieMap.values()[_int];
                if (!isoZombie.isRemoteZombie()) {
                    this.zombiesLocalOwnership++;
                } else {
                    float float0 = IsoUtils.DistanceTo(isoZombie.x, isoZombie.y, isoZombie.z, isoZombie.realx, isoZombie.realy, (float)isoZombie.realz);
                    this.zombiesDesyncAVG = this.zombiesDesyncAVG + (float0 - this.zombiesDesyncAVG) * 0.05F;
                    if (float0 > this.zombiesDesyncMax) {
                        this.zombiesDesyncMax = float0;
                    }
                }
            }

            for (IsoPlayer isoPlayer : GameClient.IDToPlayerMap.values()) {
                if (!isoPlayer.isLocalPlayer()) {
                    float float1 = IsoUtils.DistanceTo(isoPlayer.x, isoPlayer.y, isoPlayer.z, isoPlayer.realx, isoPlayer.realy, (float)isoPlayer.realz);
                    this.remotePlayersDesyncAVG = this.remotePlayersDesyncAVG + (float1 - this.remotePlayersDesyncAVG) * 0.05F;
                    if (float1 > this.remotePlayersDesyncMax) {
                        this.remotePlayersDesyncMax = float1;
                    }
                }
            }
        }
    }

    public void send(ByteBufferWriter b) {
        b.putInt(GameClient.IDToZombieMap.size());
        b.putInt(this.zombiesLocalOwnership);
        b.putFloat(this.zombiesDesyncAVG);
        b.putFloat(this.zombiesDesyncMax);
        b.putInt(this.zombiesTeleports);
        b.putInt(GameClient.IDToPlayerMap.size());
        b.putFloat(this.remotePlayersDesyncAVG);
        b.putFloat(this.remotePlayersDesyncMax);
        b.putInt(this.remotePlayersTeleports);
        Object object = null;
        short short0 = 0;
        synchronized (this.fpsArray) {
            object = (float[])this.fpsArray.clone();
            Arrays.fill(this.fpsArray, 0, this.fpsArrayCount, 0.0F);
            short0 = this.fpsArrayCount;
            this.fpsArrayCount = 0;
        }

        float float0 = (float)((Object[])object)[0];
        float float1 = (float)((Object[])object)[0];
        float float2 = (float)((Object[])object)[0];
        short[] short1 = new short[32];
        Arrays.fill(short1, (short)0);

        for (int int0 = 1; int0 < short0; int0++) {
            float float3 = (float)((Object[])object)[int0];
            if (float0 > float3) {
                float0 = float3;
            }

            if (float2 < float3) {
                float2 = float3;
            }

            float1 += float3;
        }

        float1 /= (float)short0;
        if (float1 < float0 + 16.0F) {
            float0 = float1 - 16.0F;
        }

        if (float2 < float1 + 16.0F) {
            float2 = float1 + 16.0F;
        }

        float float4 = (float1 - float0) / (float)(short1.length / 2);
        float float5 = (float2 - float1) / (float)(short1.length / 2);

        for (int int1 = 0; int1 < short0; int1++) {
            float float6 = (float)((Object[])object)[int1];
            if (float6 < float1) {
                int int2 = (int)Math.ceil((double)((float6 - float0) / float4));
                short1[int2]++;
            }

            if (float6 >= float1) {
                int int3 = (int)Math.ceil((double)((float6 - float1) / float5)) + short1.length / 2 - 1;
                short1[int3]++;
            }
        }

        b.putFloat(this.FPS);
        b.putFloat(float0);
        b.putFloat(float1);
        b.putFloat(float2);

        for (int int4 = 0; int4 < short1.length; int4++) {
            b.putShort(short1[int4]);
        }

        this.zombiesDesyncMax = 0.0F;
        this.zombiesTeleports = 0;
        this.remotePlayersDesyncMax = 0.0F;
        this.remotePlayersTeleports = 0;
        this.zombiesLocalOwnership = 0;
        this.needUpdate = true;
    }

    public void fpsProcess() {
        this.FPSAcc++;
        long _long = System.currentTimeMillis();
        if (_long - this.lastRender >= 1000L) {
            this.FPS = (float)this.FPSAcc;
            this.FPSAcc = 0;
            this.lastRender = _long;
            if (this.fpsArrayCount < this.fpsArray.length) {
                synchronized (this.fpsArray) {
                    this.fpsArray[this.fpsArrayCount] = this.FPS;
                    this.fpsArrayCount++;
                }
            }
        }
    }
}
